home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr47 / 316_01.zip / AS8.C next >
Text File  |  1993-04-01  |  32KB  |  1,683 lines

  1. /*
  2.  * z8   assembler hgw july 1983: h.-g. willers
  3.  *
  4.  *      register syntax:
  5.  *              register:               r0 - r127, r240 - r255
  6.  *              working register:       w0 - w15
  7.  *
  8.  */
  9. #include <stdio.h>
  10. #include <setjmp.h>
  11.  
  12. #define NCPS    33    /* number of characters per symbol */
  13. #define NCPLE   NCPS+2  /* number of characters per listing element */
  14. #define NLEPL   1       /* number of listing elements per line */
  15. #define    NBIN    32
  16. #define NTSYM   512     /* length of numeric-label table */
  17. #define NERR    10
  18. #define NINPUT    128
  19. #define NCODE    128
  20. #define NTIT    64
  21. #define HASHSIZ 503     /* hashtable size */
  22.             /* must be prime */
  23.             /* more primes:    */
  24.             /* 503, 607, 701, 809, 907, 1009 */
  25.             /* see: handbook of math. functions p. 879 */
  26.  
  27. #define NLIST    0
  28. #define SLIST    1
  29. #define ALIST    2
  30. #define CLIST    3
  31.  
  32. typedef    unsigned addr_t;
  33.  
  34. struct    sym
  35. {
  36.     char    *s_name;
  37.     char    s_type;
  38.     char    s_flag;
  39.     addr_t    s_addr;
  40. };
  41.  
  42. #define S_UND    0
  43. #define S_ABS    1
  44.  
  45. #define S_OP0   2
  46. #define S_OP2   4
  47. #define S_OP3   5
  48. #define S_OP4   6
  49. #define S_OP5   7
  50. #define S_OP6   8
  51. #define S_OP7   9
  52. #define S_OP8   10
  53. #define S_OP9   11
  54. #define S_OP10  12
  55. #define S_OP11  13
  56. #define S_OP12  14
  57. #define S_OP13  15
  58. #define S_OP14  16
  59. #define S_OP15  17
  60.  
  61. #define S_LIT   19
  62. #define S_REG   20
  63. #define S_WREG  21
  64. #define S_IR    22              /* register indirect */
  65. #define S_WIR   23              /* working register indirect */
  66. #define S_INDEX 24
  67.  
  68. #define    S_WORD    25
  69. #define S_ASCII    26
  70. #define S_ASCIZ    27
  71. #define S_BLKB    28
  72. #define S_PAGE    29
  73. #define S_TITLE    30
  74. #define S_BYTE    31
  75. #define S_HLIST    32
  76. #define S_OLIST    33
  77. #define S_INTEL    34
  78. #define S_MKBUG    35
  79. #define    S_LIST 36
  80. #define S_NLIST 37
  81. #define S_START 38
  82.  
  83. #define WRMASK  0xe0            /* msbs for  working reg. add. */
  84. #define CALL    0xd6            /* direct call */
  85. #define CALLI   0xd4            /* indirect call */
  86. #define SOB     0x0a            /* sob-instruction */
  87. #define JUMP    0x8d            /* jump-always instruction */
  88. #define JUMPI   0x30            /* jump indirect */
  89. #define SRP     0x31
  90. #define INCW    0x0e            /* inc working register */
  91.  
  92. #define    S_MDF    01        /* Mult. def */
  93. #define S_ASG    02        /* Assigned def */
  94.  
  95. struct    tsym
  96. {
  97.     int    t_num;
  98.     addr_t    t_addr;
  99. };
  100.  
  101. struct    tsymp
  102. {
  103.     struct    tsym *t_fp;
  104.     struct    tsym *t_bp;
  105. };
  106.  
  107. struct    addr
  108. {
  109.     char    a_type;
  110.     char    a_reg;
  111.     addr_t    a_addr;
  112. };
  113.  
  114. int    line;
  115. int    page;
  116. int    lop;
  117. int    pass;
  118. int    ntsym;
  119. int    sflag = 0;        /* symbol-table-flag */
  120. int    lflag;
  121. int    nflag;
  122. int    eflag;
  123. addr_t    laddr;
  124. int    lmode;
  125. int    ldis = 0;        /* listing disable */
  126.                 /* =1 listing is disabled */
  127. int     hlist = 1;              /* hex listing is default */
  128. int    ninst = 0;        /* number of installs into symbol table */
  129. char    *ep;
  130. char    eb[NERR];
  131. char    *ip;
  132. char    ib[NINPUT];
  133. char    *cp;
  134. char    cb[NCODE];
  135. char    tb[NTIT];
  136. int    bo;
  137. int    ba;
  138. char    bb[NBIN];
  139.  
  140. unsigned int    startadr = 0xffff;      /* start address */
  141.  
  142. char liname[80];
  143. char obname[80];    /* listing and object filenames */
  144. char stbnam[80];
  145.  
  146. jmp_buf env;
  147.  
  148. long    daytime;
  149.  
  150. long    time();
  151. char *ctime();
  152. char *malloc();
  153. struct sym *lookup();
  154. struct sym *addr1();
  155.  
  156. struct sym *dot;    /* pointer to . value into symbol table */
  157.  
  158. struct sym sym[HASHSIZ] = {0};    /* space for symbol table */
  159.  
  160. extern struct sym optab[];
  161.  
  162. struct    tsym tsym[NTSYM];
  163. struct    tsymp tsymp[10];
  164.  
  165. /* lower opcode nibbles for class-8 opcodes */
  166. /* ordered as follows:  destination, source, nibble */
  167. /* table ends at zero destination */
  168.  
  169. char c8nib[] = { S_WREG, S_WREG, 2,
  170.         S_WREG, S_WIR, 3,
  171.         S_WREG, S_WREG, 4,
  172.         S_WREG, S_REG, 4,
  173.         S_REG, S_WREG, 4,
  174.         S_REG, S_REG, 4,
  175.         S_WREG, S_WIR, 5,
  176.         S_WREG, S_IR, 5,
  177.         S_REG, S_WIR, 5,
  178.         S_REG, S_IR, 5,
  179.         S_WREG, S_LIT, 6,
  180.         S_REG, S_LIT, 6,
  181.         S_WIR, S_LIT, 7,
  182.         S_IR, S_LIT, 7,
  183.         0, 0, 0
  184.         };
  185.  
  186. char movtab[] = { S_WREG, S_LIT, 0x0c,
  187.         S_WREG, S_REG, 0x08,
  188.         S_WREG, S_WREG, 0x08,
  189.         S_REG,  S_WREG, 0x09,
  190.         S_WREG, S_INDEX, 0xc7,
  191.         S_INDEX, S_WREG, 0xd7,
  192.         S_WREG, S_WIR, 0xe3,
  193.         S_WIR, S_WREG, 0xf3,
  194.         S_REG, S_REG, 0xe4,
  195.         S_REG, S_IR, 0xe5,
  196.         S_REG, S_LIT, 0xe6,
  197.         S_IR, S_LIT, 0xe7,
  198.         S_IR, S_REG, 0xf5,
  199.         S_WIR, S_REG, 0xf5,
  200.         S_IR, S_WREG, 0xf5,
  201.         S_WIR, S_WREG, 0xf5,
  202.         0, 0, 0
  203.         };
  204.  
  205. char c13tab[] = {S_WREG, S_WIR, 1,
  206.         S_WIR, S_WREG, 2,
  207.         0, 0, 0
  208.         };
  209.  
  210. FILE    *lfp;
  211. FILE    *ofp;
  212. FILE    *sfp;
  213.  
  214. char *strrchr();
  215. char *strchr();
  216.  
  217. main(argc, argv)
  218. char *argv[];
  219. {
  220.     register char *p;
  221.     register c, i;
  222.     struct tsym *tp;
  223.     char *iptr;        /* index-pointer */
  224.     char *fn;
  225.     FILE *afile();
  226.  
  227.     fn = NULL;
  228.     for (i=1; i<argc; ++i) {
  229.         p = argv[i];
  230.         if (*p == '-') {
  231.             ++p;
  232.             while (c = *p++)
  233.                 switch(c) {
  234.  
  235.                 case 'l':
  236.                 case 'L':
  237.                     ++lflag;
  238.                     break;
  239.  
  240.                 case 'n':
  241.                 case 'N':
  242.                     ++nflag;
  243.                     break;
  244.  
  245.                 default:
  246.                     fprintf(stderr, "%c: ignored.\n", c);
  247.                 }
  248.         } else
  249.             fn = p;
  250.     }
  251.     if (fn != NULL) {
  252.         sfp = afile(fn, 0);
  253.         if((iptr = strrchr(fn, '/')) == NULL)
  254.             strcpy(liname, fn);
  255.         else
  256.             strcpy(liname, ++iptr);
  257.         if((iptr = strrchr(liname, '.')) != NULL)
  258.             *iptr = 0;              /* truncate suffix (if any) */
  259.         if (!nflag) {
  260.             strcpy(obname, liname);
  261.             strcat(obname, ".o");
  262.         }
  263.         if (lflag) {
  264.             strcat(liname, ".l");
  265.             lfp = afile(liname, 1);
  266.         }
  267.         if(strcmp (fn, obname) == 0) {
  268.             fprintf(stderr, "Would overwrite %s\n", fn);
  269.             exit(1);
  270.         }
  271.         ofp = afile(obname, 1);
  272.         for (pass=0; pass<2; ++pass) {
  273.             if(pass == 0)
  274.                 insopc();          /* install opcodes */
  275.             dot = lookup(".", 0, 0);   /* locate . in table */
  276.             dot->s_type = S_ABS;
  277.             dot->s_flag = S_ASG;
  278.             dot->s_addr = 0;
  279.             line = 0;
  280.             page = 1;
  281.             lop =  60;
  282.             if (pass == 1) {
  283.                 rewind(sfp);
  284.                 for (i=0; i<10; ++i) {
  285.                     tsymp[i].t_fp = NULL;
  286.                     tsymp[i].t_bp = NULL;
  287.                     tp = tsym;
  288.                     while (tp < &tsym[ntsym]) {
  289.                         if (tp->t_num == i) {
  290.                             tsymp[i].t_fp = tp;
  291.                             break;
  292.                         }
  293.                         ++tp;
  294.                     }
  295.                 }
  296.             }
  297.             while (fgets(ib, sizeof ib, sfp) != NULL) {
  298.                 iptr = strchr(ib,'\n');
  299.                 *iptr = 0;
  300.                 ++line;
  301.                 cp = cb;
  302.                 ep = eb;
  303.                 ip = ib;
  304.                 eflag = 0;
  305.                 setjmp(env);
  306.                 if (eflag == 0)
  307.                     xasm();
  308.                 if (pass == 1) {
  309.                     diag();
  310.                     list();
  311.                 }
  312.             }
  313.         }
  314.         if (!nflag) {
  315.             bflush();
  316.             beof();
  317.         }
  318.         prstb();
  319.         prstat();
  320.     }
  321. }
  322.  
  323. FILE *
  324. afile(fn, wf)
  325. char *fn;
  326. {
  327.     register FILE *fp;
  328.  
  329.     fp = fopen(fn, wf?"w":"r");
  330.     if (fp == NULL) {
  331.         fprintf(stderr, "%s: cannot open.\n", fn);
  332.         exit(1);
  333.     }
  334.     return (fp);
  335. }
  336.  
  337. xasm()
  338. {
  339.     register c;
  340.     register addr_t a;
  341.     struct sym *sp;
  342.     struct tsym *tp;
  343.     int b, d, op;
  344.     char *p, id[NCPS];
  345.     struct addr a1, a2;
  346.  
  347.     laddr = dot->s_addr;
  348.     lmode = SLIST;
  349. loop:
  350.     while ((c = getnb()) == ';')
  351.         ;
  352.     if (c == 0 || c == '/')
  353.         return;
  354.     if (isdigit(c)) {
  355.         if (getnb() != ':')
  356.             err('q');
  357.         c -= '0';
  358.         if (pass == 0) {
  359.             if (ntsym >= NTSYM)
  360.                 error("Too many temp. symbols!\n");
  361.             tsym[ntsym].t_num = c;
  362.             tsym[ntsym].t_addr = dot->s_addr;
  363.             ++ntsym;
  364.         }
  365.         else {
  366.             tp = tsymp[c].t_fp;
  367.             tsymp[c].t_bp = tp;
  368.             tsymp[c].t_fp = NULL;
  369.             ++tp;
  370.             while (tp < &tsym[ntsym]) {
  371.                 if (tp->t_num == c) {
  372.                     tsymp[c].t_fp = tp;
  373.                     break;
  374.                 }
  375.                 ++tp;
  376.             }
  377.         }
  378.         goto loop;
  379.     }
  380.     if (!isidc(c))
  381.         err('q');
  382.     getid(c, id);
  383.     if ((c = getnb()) == ':') {
  384.         sp = lookup(id, 1, 0);
  385.         if (pass == 0) {
  386.             if (sp->s_type!=S_UND && (sp->s_flag&S_ASG)==0)
  387.                 sp->s_flag |= S_MDF;
  388.             sp->s_type = S_ABS;
  389.             sp->s_addr = dot->s_addr;
  390.         } else {
  391.             if ((sp->s_flag&S_MDF) != 0)
  392.                 err('m');
  393.             if (sp->s_type!=S_ABS || sp->s_addr!=dot->s_addr)
  394.                 err('p');
  395.         }
  396.         lmode = ALIST;
  397.         goto loop;
  398.     }
  399.     if (c == '=') {
  400.         sp = lookup(id, 1, 0);
  401.         if (sp->s_type!=S_UND && (sp->s_flag&S_ASG)==0)
  402.             err('m');
  403.         expr(&a1);
  404.         sp->s_addr = laddr = a1.a_addr;
  405.         sp->s_flag = S_ASG;
  406.         sp->s_type = a1.a_type;
  407.         lmode = ALIST;
  408.         goto loop;
  409.     }
  410.     unget(c);
  411.     lmode = CLIST;
  412.     if ((sp=lookup(id, 0, 0)) == NULL) {
  413.         err('o');
  414.         return;
  415.     }
  416.     op = sp->s_addr;
  417.     switch(sp->s_type) {
  418.  
  419.     case S_HLIST:
  420.     case S_OLIST:
  421.         hlist = op;
  422.         lmode = SLIST;
  423.         break;
  424.  
  425.     case S_LIST:
  426.         ldis = 0;
  427.         break;
  428.  
  429.     case S_NLIST:
  430.         ldis = 1;
  431.         break;
  432.  
  433.     case S_BYTE:
  434.     case S_WORD:
  435.         do {
  436.             expr(&a1);
  437.             a = a1.a_addr;
  438.             if (sp->s_type == S_BYTE) {
  439.                 bcheck(a, 't');
  440.                 outb(a);
  441.             } else
  442.                 outw(a);
  443.         } while ((c = getnb()) == ',');
  444.         unget(c);
  445.         break;
  446.  
  447.     case S_ASCII:
  448.     case S_ASCIZ:
  449.         if ((d = getnb()) == 0)
  450.             err('q');
  451.         while ((c = get()) != 0 && c != d)
  452.             outb(c);
  453.         if (c == 0)
  454.             err('q');
  455.         if (sp->s_type == S_ASCIZ)
  456.             outb(0);
  457.         break;
  458.  
  459.     case S_BLKB:
  460.         expr(&a1);
  461.         a = a1.a_addr;
  462.         if ((c = getnb()) == ',') {
  463.             expr(&a1);
  464.             b = a1.a_addr;
  465.         } else {
  466.             unget(c);
  467.             b = 0;
  468.         }
  469.         while (a--)
  470.             outb(b);
  471.         lmode = ALIST;
  472.         break;
  473.  
  474.     case S_TITLE:
  475.         p = tb;
  476.         if (c = getnb()) {
  477.             do {
  478.                 if (p < &tb[NTIT-1])
  479.                     *p++ = c;
  480.             } while (c = get());
  481.         }
  482.         *p = 0;
  483.         unget(c);
  484.  
  485.     case S_PAGE:
  486.         lop = 60;
  487.         lmode = NLIST;
  488.         break;
  489.  
  490.     case S_START:
  491.         expr(&a1);
  492.         startadr = a1.a_addr;
  493.         break;
  494.  
  495.     case S_OP0:
  496.         outb(op);
  497.         break;
  498.  
  499.     case S_OP2:
  500.         addr(&a1);
  501.         if(a1.a_type == S_LIT) {
  502.             a = a1.a_addr;                  /* only banks 0 - 7 */
  503.             if((0 <= a) && (a < 128)) {
  504.                 if(a % 16) aerr();
  505.                 else {
  506.                     outb(SRP); outb(a);
  507.                     break;
  508.                 }
  509.             }
  510.         }
  511.         aerr();
  512.         break;
  513.  
  514.     case S_OP3:
  515.         addr(&a1);
  516.         if(a1.a_type == S_REG) {
  517.             outb(op);
  518.             outb(a1.a_addr);
  519.             break;
  520.         }
  521.         if(a1.a_type == S_WREG) {
  522.             outb(op);
  523.             outb(a1.a_addr | WRMASK);
  524.             break;
  525.         }
  526.         if(a1.a_type == S_IR) {
  527.             outb(op + 1);
  528.             outb(a1.a_addr);
  529.             break;
  530.         }
  531.         if(a1.a_type == S_WIR) {
  532.             outb(op + 1);
  533.             outb(a1.a_addr | WRMASK);
  534.             break;
  535.         }
  536.         aerr();
  537.         break;
  538.  
  539.     case S_OP4:
  540.         addr(&a1);
  541.         if(a1.a_type == S_ABS) {
  542.             outb(CALL);
  543.             outw(a1.a_addr);
  544.             break;
  545.         }
  546.         if(a1.a_type == S_IR) {
  547.             a = a1.a_addr;
  548.             even(a);
  549.             outb(CALLI);
  550.             outb(a);
  551.             break;
  552.         }
  553.  
  554.         if(a1.a_type == S_WIR) {
  555.             a = a1.a_addr;
  556.             even(a);
  557.             outb(CALLI);
  558.             outb(a | WRMASK);
  559.             break;
  560.         }
  561.         aerr();
  562.         break;
  563.  
  564.     case S_OP5:
  565.         addr(&a1);
  566.         if(a1.a_type == S_ABS ) {
  567.             outb(op);
  568.             outw(a1.a_addr);
  569.             break;
  570.         }
  571.         if(a1.a_type == S_IR) {
  572.             if(op != JUMP) aerr();
  573.             outb(JUMPI);
  574.             a = a1.a_addr;
  575.             even(a);
  576.             outb(a);
  577.             break;
  578.         }
  579.         if(a1.a_type == S_WIR) {
  580.             if(op != JUMP) aerr();
  581.             outb(JUMPI);
  582.             a = (a1.a_addr | WRMASK);
  583.             even(a);
  584.             outb(a);
  585.             break;
  586.         }
  587.         aerr();
  588.         break;
  589.  
  590.     case S_OP7:
  591.         addr(&a1);
  592.         if(a1.a_type == S_WREG)
  593.             op |=  (a1.a_addr << 4);
  594.         else
  595.             aerr();
  596.         comma();
  597.  
  598.     case S_OP6:
  599.         expr(&a1);
  600.         a = a1.a_addr - dot->s_addr - 2;
  601.         bcheck(a, 'a');
  602.         outb(op);
  603.         outb(a);
  604.         break;
  605.  
  606.     case S_OP8:
  607.         addr(&a1);
  608.         comma();
  609.         addr(&a2);
  610.         if((a = check(a1.a_type, a2.a_type, c8nib)) == 0) {
  611.             aerr();
  612.             break;
  613.         }
  614.         op |= a;        /* mask in lower opcode nibble */
  615.         if((a1.a_type == S_WREG) && (a2.a_type == S_WREG)) {
  616.             outb(op);
  617.             outb(a1.a_addr | ((a2.a_addr) << 4));
  618.             break;
  619.         }
  620.         if((a1.a_type == S_WIR) && (a2.a_type == S_WREG)) {
  621.             outb(op);
  622.             outb(a1.a_addr | ((a2.a_addr) << 4));
  623.             break;
  624.         }
  625.         if(a1.a_type == S_LIT) {
  626.             outb(op);
  627.             if((a2.a_type == S_WREG) || (a2.a_type == S_WIR))
  628.                 outb(a2.a_addr | WRMASK);
  629.             else
  630.                 outb(a2.a_addr);
  631.             outb(a1.a_addr);        /* immediate value */
  632.             break;
  633.         }
  634.         outb(op);
  635.         if((a1.a_type == S_WREG) || (a1.a_type == S_WIR))
  636.             outb(a1.a_addr | WRMASK);
  637.         else
  638.             outb(a1.a_addr);
  639.         if((a2.a_type == S_WREG) || (a2.a_type == S_WIR))
  640.             outb(a2.a_addr | WRMASK);
  641.         else
  642.             outb(a2.a_addr);
  643.         break;
  644.  
  645.     case S_OP9:
  646.         addr(&a1);
  647.         comma();
  648.         addr(&a2);
  649.         if((a = check(a1.a_type, a2.a_type, movtab)) > 0) {
  650.             if(a < 20) {
  651.                 if(a2.a_type == S_WREG) {
  652.                     op = a | (a2.a_addr << 4);
  653.                     a = a1.a_addr;
  654.                     if(a1.a_type == S_WREG)
  655.                         a |= WRMASK;
  656.                 }
  657.                 else {
  658.                     op = a | (a1.a_addr << 4);
  659.                     a = a2.a_addr;
  660.                     if(a2.a_type == S_WREG)
  661.                         a |= WRMASK;
  662.                 }
  663.                 outb(op); outb(a); break;
  664.             }
  665.             switch(a & 0377) {
  666.  
  667.                 case 0xc7:
  668.                     b = a1.a_addr | (a2.a_addr << 4);
  669.                     d = a1.a_reg;
  670.                     break;
  671.  
  672.                 case 0xd7:
  673.                     b = a2.a_addr | (a1.a_addr << 4);
  674.                     d = a2.a_reg;
  675.                     break;
  676.  
  677.                 case 0xe3:
  678.                 case 0xf3:
  679.                     b = a1.a_addr | (a2.a_addr << 4);
  680.                     d = 10000;
  681.                     break;
  682.  
  683.                 case 0xe4:
  684.                 case 0xe5:
  685.                 case 0xf5:
  686.                     if((a1.a_type == S_WIR) || (a1.a_type == S_WREG))
  687.                         b = a1.a_addr | WRMASK;
  688.                     else
  689.                         b = a1.a_addr;
  690.                     if((a2.a_type == S_WIR) || (a2.a_type == S_WREG))
  691.                         d = a2.a_addr | WRMASK;
  692.                     else
  693.                         d = a2.a_addr;
  694.                     break;
  695.  
  696.                 case 0xe6:
  697.                 case 0xe7:
  698.                     if((a2.a_type == S_WIR) || (a2.a_type == S_WREG))
  699.                         b = a2.a_addr | WRMASK;
  700.                     else
  701.                         b = a2.a_addr;
  702.                     d = a1.a_addr;
  703.                     break;
  704.             }
  705.             outb(a); outb(b);
  706.             if(d != 10000) outb(d);
  707.             break;
  708.         }
  709.         else
  710.             aerr();
  711.         break;
  712.  
  713.     case S_OP10:
  714.         addr(&a1);
  715.         if(a1.a_type == S_WREG) {
  716.             even(a1.a_addr);
  717.             outb(op);
  718.             outb(a1.a_addr | WRMASK);
  719.             break;
  720.         }
  721.         if(a1.a_type == S_REG) {
  722.             even(a1.a_addr);
  723.             outb(op); outb(a1.a_addr);
  724.             break;
  725.         }
  726.         if(a1.a_type == S_WIR) {
  727.             outb(op + 1);
  728.             outb(a1.a_addr | WRMASK);
  729.             break;
  730.         }
  731.         if(a1.a_type == S_IR) {
  732.             outb(op + 1);
  733.             outb(a1.a_addr);
  734.             break;
  735.         }
  736.         aerr();
  737.         break;
  738.  
  739.     case S_OP11:
  740.     case S_OP12:
  741.         addr(&a1);
  742.         if(a1.a_type == S_WREG) {
  743.             if(sp->s_type == S_OP11) {
  744.                 outb(INCW | (a1.a_addr << 4));
  745.                 break;
  746.             }
  747.             else {
  748.                 outb(op);
  749.                 outb(a1.a_addr | WRMASK);
  750.                 break;
  751.             }
  752.         }
  753.         if(a1.a_type == S_REG) {
  754.             outb(op);
  755.             outb(a1.a_addr);
  756.             break;
  757.         }
  758.         if(a1.a_type == S_WIR) {
  759.             outb(op + 1);
  760.             outb(a1.a_addr | WRMASK);
  761.             break;
  762.         }
  763.         if(a1.a_type == S_IR) {
  764.             outb(op + 1);
  765.             outb(a1.a_addr);
  766.             break;
  767.         }
  768.         aerr();
  769.         break;
  770.  
  771.     case S_OP13:
  772.         addr(&a1);
  773.         comma();
  774.         addr(&a2);
  775.         if((a = check(a1.a_type, a2.a_type, c13tab)) > 0) {
  776.             if(a == 1)
  777.                 outb(sp->s_flag);
  778.             else
  779.                 outb(sp->s_addr);
  780.             if (a1.a_type == S_WREG)
  781.                 outb(a2.a_addr | (a1.a_addr << 4));
  782.             else
  783.                 outb(a1.a_addr | (a2.a_addr << 4));
  784.             break;
  785.         }
  786.         else  {
  787.             aerr();
  788.             break;
  789.         }
  790.  
  791.  
  792.     case S_OP14:
  793.     case S_OP15:
  794.         addr(&a1);
  795.         comma();
  796.         addr(&a2);
  797.         if((a1.a_type == S_WIR) && (a2.a_type == S_WIR)) {
  798.             outb(op);
  799.             outb(a1.a_addr | (a2.a_addr << 4));
  800.             break;
  801.         }
  802.         aerr();
  803.         break;
  804.  
  805.  
  806.     default:
  807.         err('o');
  808.     }
  809.     goto loop;
  810. }
  811.  
  812. check(source, dest, table)
  813. register char dest, source;
  814. char *table;
  815. {       register char *ptr;
  816.  
  817.     ptr = table;                   /* get address of legal var. table */
  818.     while(*ptr != 0) {
  819.         if(*ptr++ == dest ) {
  820.             if(*ptr++ == source)
  821.                 return(*ptr);   /* return nibble */
  822.             else
  823.                 ptr++;
  824.         }
  825.         else {
  826.             ptr++; ptr++;
  827.         }
  828.     }
  829.     return(0);                      /* not found */
  830. }
  831.  
  832. /* check for even argument */
  833. even(arg)
  834. int arg;
  835. {       if(arg & 1) err('e'); }
  836.  
  837. addr(ap)
  838. register struct addr *ap;
  839. {       register int c, n;
  840.     register addr_t;
  841.     register struct sym *sp;
  842.     char id[NCPS];
  843.  
  844.     if((c = getnb()) == '$') {
  845.         expr(ap);
  846.         if ((ap->a_type != S_UND) && (ap->a_type != S_ABS))
  847.             aerr();
  848.         ap->a_type = S_LIT;
  849.         return;
  850.     }
  851.     if(c == '(') {
  852.         if(isidc(c = getnb())) {
  853.             getid(c, id);
  854.             if(getnb() != ')') err('q');
  855.             if(chkreg(ap, id) > 0) {
  856.                 if(ap->a_type == S_REG) {
  857.                     ap->a_type = S_IR;
  858.                     return;
  859.                 }
  860.                 if(ap->a_type == S_WREG) {
  861.                     ap->a_type = S_WIR;
  862.                     return;
  863.                 }
  864.                 err('q');
  865.             }
  866.             else {
  867.                 sp = lookup(id, 0, 0);
  868.                 if(sp == NULL) {
  869.                     err('u');
  870.                     return;
  871.                 }
  872.                 else {
  873.                     if(sp->s_type == S_REG) {
  874.                         ap->a_type = S_IR;
  875.                         ap->a_addr = sp->s_addr;
  876.                         return;
  877.                     }
  878.                     if(sp->s_type == S_WREG) {
  879.                         ap->a_type = S_WIR;
  880.                         ap->a_addr = sp->s_addr;
  881.                         return;
  882.                     }
  883.                     err('q');
  884.                     return;
  885.                 }
  886.             }
  887.         }
  888.         else
  889.             err('q');
  890.     }
  891.     unget(c);
  892.     expr(ap);
  893.     if(ap->a_type != S_REG)
  894.         return;
  895.     if((c = getnb()) != '(') {
  896.         unget(c);
  897.         return;
  898.     }
  899.     /* for indexed addressing a_addr contains index part */
  900.     /* a_reg contains offset part */
  901.     if(isidc(c = getnb())) {
  902.         getid(c, id);
  903.         if(getnb() != ')') err('q');
  904.         n = ap->a_addr;                 /* save offset */
  905.         if(chkreg(ap, id) > 0) {
  906.             if(ap->a_type == S_WREG) {
  907.                 ap->a_type = S_INDEX;
  908.                 ap->a_reg = n;
  909.                 return;
  910.             }
  911.             err('q');
  912.         }
  913.         else {
  914.             sp = lookup(id, 0, 0);
  915.             if(sp == NULL) {
  916.                 err('u');
  917.                 return;
  918.             }
  919.             else {
  920.                 if(sp->s_type == S_WREG) {
  921.                     ap->a_type = S_INDEX;
  922.                     ap->a_addr = sp->s_addr;
  923.                     ap->a_reg = n;
  924.                     return;
  925.                 }
  926.                 err('q');
  927.             }
  928.         }
  929.     }
  930.     else
  931.         err('Q');
  932.     return;
  933. }
  934.  
  935. expr(ap)
  936. register struct addr *ap;
  937. {
  938.     register int c;
  939.     struct addr right;
  940.  
  941.     term(ap);
  942.     if (ap->a_type != S_ABS)
  943.         return;
  944.     for (;;) {
  945.         c = getnb();
  946.         if ((c=='<' || c=='>') && c!=getnb())
  947.             err('q');
  948.         if (!any(c, "+-*%&|><^")) {
  949.             unget(c);
  950.             break;
  951.         }
  952.         term(&right);
  953.         if (right.a_type != S_ABS)
  954.             err('r');
  955.         switch(c) {
  956.  
  957.         case '+':
  958.             ap->a_addr += right.a_addr;
  959.             break;
  960.  
  961.         case '-':
  962.             ap->a_addr -= right.a_addr;
  963.             break;
  964.  
  965.         case '*':
  966.             ap->a_addr *= right.a_addr;
  967.             break;
  968.  
  969.         case '%':
  970.             ap->a_addr /= right.a_addr;
  971.             break;
  972.  
  973.         case '&':
  974.             ap->a_addr &= right.a_addr;
  975.             break;
  976.  
  977.         case '|':
  978.             ap->a_addr |= right.a_addr;
  979.             break;
  980.  
  981.         case '^':
  982.             ap->a_addr ^= right.a_addr;     /* xor */
  983.             break;
  984.  
  985.         case '>':
  986.             ap->a_addr >>= right.a_addr;
  987.             break;
  988.  
  989.         case '<':
  990.             ap->a_addr <<= right.a_addr;
  991.         }
  992.     }
  993. }
  994.  
  995. term(ap)
  996. register struct addr *ap;
  997. {
  998.     register int c;
  999.     register int n, r, v;
  1000.     char id[NCPS];
  1001.     register struct sym *sp;
  1002.     register struct tsym *tp;
  1003.  
  1004.     c = getnb();
  1005.     if (c == '[') {
  1006.         expr(ap);
  1007.         if (getnb() != ']')
  1008.             err('q');
  1009.         return;
  1010.     }
  1011. /*    added literal    hgw    */
  1012.     if (c == '\'') {
  1013.         c = get();
  1014.         c = c&0177;
  1015.         ap->a_type = S_ABS;
  1016.         ap->a_addr = c;
  1017.         return;
  1018.     }
  1019. /*      operator-precedence of unary operators changed [hgw]    */
  1020.     if (c == '-' || c == '!') {
  1021.         term(ap);
  1022.         if (ap->a_type != S_ABS) {
  1023.             err('r');
  1024.             ap->a_type = S_ABS;
  1025.         }
  1026.         if (c == '-')
  1027.             ap->a_addr = -ap->a_addr;
  1028.         else
  1029.             ap->a_addr = ~ap->a_addr;
  1030.         return;
  1031.     }
  1032.     if (isdigit(c)) {
  1033.         ap->a_type = S_ABS;
  1034.         r = 10;
  1035.         if (c == '0') {
  1036.             r = 8;
  1037.             if ((c = get()) == 'x') {
  1038.                 r = 16;
  1039.                 c = get();
  1040.             }
  1041.             else
  1042.                 if (c  == 'B') {
  1043.                     r = 2;
  1044.                     c = get();
  1045.                 }
  1046.         }
  1047.         n = 0;
  1048.         while ((v = digit(c, r)) >= 0) {
  1049.             n = r*n + v;
  1050.             c = get();
  1051.         }
  1052.         if (c=='f' || c=='b') {
  1053.             if ((n < 10) && (n >= 0)) {
  1054.                 if (c == 'f')
  1055.                     tp = tsymp[n].t_fp; else
  1056.                     tp = tsymp[n].t_bp;
  1057.                 if (tp != NULL) {
  1058.                     ap->a_addr = tp->t_addr;
  1059.                     return;
  1060.                 }
  1061.             }
  1062.             err('u');
  1063.             ap->a_addr = 0;
  1064.             return;
  1065.         }
  1066.         unget(c);
  1067.         ap->a_addr = n;
  1068.         return;
  1069.     }
  1070.     if (isidc(c)) {
  1071.         getid(c, id);
  1072.         if(chkreg(ap, id) > 0 ) return;
  1073.         if ((sp = lookup(id, 0, 0)) != NULL) {
  1074.             ap->a_type = sp->s_type;
  1075.             ap->a_addr = sp->s_addr;
  1076.             return;
  1077.         }
  1078.         err('u');
  1079.         ap->a_type = S_ABS;
  1080.         ap->a_addr = 0;
  1081.         return;
  1082.     }
  1083.     err('q');
  1084. }
  1085.  
  1086. /* check for register usage */
  1087. /* w must be in the range 0 - 15 */
  1088. /* r must be in the range 0 - 127, or 240 - 255 */
  1089. /* if a valid register, set type in the supplied structure */
  1090. /* and return +1 */
  1091. /* otherwise return 0 */
  1092.  
  1093. chkreg(ap, id)
  1094. register struct addr *ap;
  1095. char *id;
  1096. {
  1097.     register char *ptr;
  1098.     register int n;
  1099.  
  1100.     ptr = id;               /* get address of token */
  1101.     if(*ptr == 'w') {
  1102.         n = getnum(ptr, 2);      /* 2 digits max */
  1103.         if((0 <= n) && (n < 16)) {
  1104.             ap->a_type = S_WREG;     /* short */
  1105.             ap->a_addr = n;
  1106.             return(1);
  1107.         }
  1108.     }
  1109.     if(*ptr == 'r') {
  1110.         n = getnum(ptr, 3);     /* 3 digits max */
  1111.         if(((0 <= n) && (n < 128)) || ((240 <= n) && (n < 256))) {
  1112.             ap->a_type = S_REG;      /* long */
  1113.             ap->a_addr = n;
  1114.             return(1);
  1115.         }
  1116.     }
  1117.     return(0);
  1118. }
  1119.  
  1120. /* get number of working register */
  1121. getnum(str, nmax)
  1122. char *str;
  1123. int nmax;
  1124. {
  1125.     register int n, c, i;
  1126.     register int imax;
  1127.     register char *ptr;
  1128.  
  1129.     ptr = str;
  1130.     imax = nmax;
  1131.     ptr++;                  /* skip leading 'w', 'r' or 'R' */
  1132.     n = i = 0;
  1133.     while((i < imax) && ((c = *ptr++) != '\0')) {
  1134.         n = 10 * n + c - '0';
  1135.         i++;
  1136.     }
  1137.     if((i == imax) && (*ptr != '\0')) return(-1);  /* since no '\0' reached */
  1138.     else return(n);
  1139. }
  1140.  
  1141. digit(c, r)
  1142. register c, r;
  1143. {
  1144.     if (r == 16) {
  1145.         if (c >= 'A' && c <= 'F')
  1146.             return (c - 'A' + 10);
  1147.         if (c >= 'a' && c <= 'f')
  1148.             return (c - 'a' + 10);
  1149.     }
  1150.     if (r == 8) {
  1151.         if (c >= '0' && c <= '7')
  1152.             return (c - '0');
  1153.         else
  1154.             return (-1);
  1155.     }
  1156.     if (r == 2) {
  1157.         if (c >= '0' && c <= '1')
  1158.             return (c - '0');
  1159.         else
  1160.             return (-1);
  1161.     }
  1162.     if (c >= '0' && c <= '9')
  1163.         return (c - '0');
  1164.     return (-1);
  1165. }
  1166.  
  1167. any(c, s)
  1168. register c;
  1169. register char *s;
  1170. {
  1171.     register char b;
  1172.  
  1173.     while (b = *s++)
  1174.         if (b == c)
  1175.             return (1);
  1176.     return (0);
  1177. }
  1178.  
  1179. list()
  1180. {
  1181.     register char *wp;
  1182.     register nb;
  1183.  
  1184.     if (lfp==NULL || lmode==NLIST || ldis==1)
  1185.         return;
  1186.     slew();
  1187.     while (ep < &eb[NERR])
  1188.         *ep++ = ' ';
  1189.     fprintf(lfp, "%.10s", eb);
  1190.     if (lmode == SLIST) {
  1191.         fprintf(lfp, "%24s%5d %s\n", "", line, ib);
  1192.         return;
  1193.     }
  1194.     fprintf(lfp, hlist?"   %04x":" %06o", laddr);
  1195.     if (lmode == ALIST) {
  1196.         fprintf(lfp, "%17s%5d %s\n", "", line, ib);
  1197.         return;
  1198.     }
  1199.     wp = cb;
  1200.     nb = cp - cb;
  1201.     list1(wp, nb, 1);
  1202.     fprintf(lfp, " %5d %s\n", line, ib);
  1203.     while ((nb -= 4) > 0) {
  1204.         wp += 4;
  1205.         slew();
  1206.         fprintf(lfp, "%17s", "");
  1207.         list1(wp, nb, 0);
  1208.         putc('\n', lfp);
  1209.     }
  1210. }
  1211.  
  1212. list1(wp, nb, f)
  1213. register char *wp;
  1214. register nb;
  1215. {
  1216.     register i;
  1217.  
  1218.     if (nb > 4)
  1219.         nb = 4;
  1220.     for (i=0; i<nb; ++i)
  1221.         fprintf(lfp, hlist?"  %02x":" %03o", (*wp++)&0377);
  1222.     if (f)
  1223.         while (i < 4) {
  1224.             fprintf(lfp, "    ");
  1225.             ++i;
  1226.         }
  1227. }
  1228.  
  1229. slew()
  1230. {
  1231.     if(lfp == NULL)
  1232.         return;
  1233.     if (lop++ >= 60) {
  1234.         daytime = time(NULL);
  1235.         if (page != 1 )       /* suppress form-feed on 1st page */
  1236.             fprintf(lfp, "\f");
  1237.         fprintf(lfp, "Z8 Assembler: h.-g. willers\tpage %d\t\t%s", page++, ctime(&daytime));
  1238.         fprintf(lfp, "%s\n\n", tb);
  1239.         lop = 4;
  1240.     }
  1241. }
  1242.  
  1243.  
  1244. /*    print symbol table    */
  1245. prstb()
  1246. {
  1247.     register struct sym *sp;
  1248.     register char *p1;
  1249.     register char ochar;
  1250.     register int i, j;
  1251.     int cntr;
  1252.  
  1253.     if(!lflag) return;
  1254.     if(lflag) {
  1255.         lop = 60;        /* force new page */
  1256.         slew();
  1257.         fprintf(lfp, "Symboltable dump\n\n");
  1258.     }
  1259.     sp = &sym[0];        /* get pointer to begin of symbol table */
  1260.     /* remove any item not assigned or label */
  1261.     for(i= 0; i < HASHSIZ; i++) {
  1262.         p1 = sp->s_name;
  1263.         if(p1 != 0) {
  1264.             if(sp->s_type != S_ABS)
  1265.                 if(sp->s_flag != S_ASG)
  1266.                     sp->s_name = 0;
  1267.         }
  1268.         sp++;
  1269.     }
  1270.     dot->s_name = 0;                /* remove '.' */
  1271.     cntr = 0;
  1272.     sp = &sym[0];
  1273.     for(i=0; i < HASHSIZ; i++) {
  1274.         p1 = sp->s_name;
  1275.         if(p1 == 0) sp++;
  1276.         else {
  1277.             if(cntr != 0)
  1278.                 fprintf(lfp, "    ");
  1279.             j = 0;
  1280.             while(j < (NCPS - 1)) {
  1281.                 j++;
  1282.                 if((ochar = *p1++) != '\0')
  1283.                     fprintf(lfp,"%c", ochar);
  1284.                 else {
  1285.                     fprintf(lfp,"%c", ' ');
  1286.                     break;
  1287.                 }
  1288.             }
  1289.             while(j < NCPLE) {
  1290.                 j++;
  1291.                 fprintf(lfp, "%c", ' ');
  1292.             }
  1293.             j = sp->s_addr;
  1294.             fprintf(lfp, hlist?"  %04x":"%06o", j);
  1295.             cntr++;
  1296.             if(cntr == NLEPL) {
  1297.                 cntr = 0;
  1298.                 fprintf(lfp,"\n");
  1299.                 slew();
  1300.             }
  1301.             sp++;
  1302.         }
  1303.     }
  1304.     fprintf(lfp, "\n");
  1305.     slew();
  1306. }
  1307.  
  1308. /*    print assembler statistics    */
  1309. prstat()
  1310. {
  1311.     register int i;
  1312.  
  1313.     if(!lflag)
  1314.         return;
  1315.     if(lop > 50)            /* force new page if neccesary */
  1316.         lop = 60;
  1317.  
  1318.     slew();
  1319.     i = HASHSIZ;
  1320.     fprintf(lfp, "\n\n symboltable-size is %d ; %d entries used\n", i, ninst);
  1321. }
  1322.  
  1323. bcheck(n, f)
  1324. register n;
  1325. {
  1326.     if((n < -128 || n > 127) && ((n & ~(0xff)) != 0))
  1327.         err(f);
  1328. }
  1329.  
  1330. comma()
  1331. {
  1332.     if (getnb() != ',')
  1333.         err('q');
  1334. }
  1335.  
  1336. getid(c, id)
  1337. register c;
  1338. char *id;
  1339. {
  1340.     register char *p;
  1341.  
  1342.     p = id;
  1343.     do {
  1344.         if (p < ((&id[NCPS]) - 1))
  1345.             *p++ = c;
  1346.     } while (isidc(c=get()) || c=='\'' || (c>='0' && c<='9'));
  1347.     unget(c);
  1348.     while (p < &id[NCPS])
  1349.         *p++ = 0;
  1350. }
  1351.  
  1352. getnb()
  1353. {
  1354.     register c;
  1355.  
  1356.     while ((c=get())==' ' || c=='\t')
  1357.         ;
  1358.     return (c);
  1359. }
  1360.  
  1361. get()
  1362. {
  1363.     register c;
  1364.  
  1365.     if ((c = *ip) != '\0')
  1366.         ++ip;
  1367.     return (c);
  1368. }
  1369.  
  1370. unget(c)
  1371. {
  1372.     if (c != '\0')
  1373.         --ip;
  1374. }
  1375.  
  1376. isdigit(c)
  1377. register c;
  1378. {
  1379.     return (c>='0' && c<='9');
  1380. }
  1381.  
  1382. isidc(c)
  1383. register c;
  1384. {
  1385.     if (c == '_')
  1386.         return (1);
  1387.     if (c == '.')
  1388.         return (1);
  1389.     if (c>='a' && c<='z')
  1390.         return (1);
  1391.     if (c>='A' && c<='Z')
  1392.         return (1);
  1393.     return (0);
  1394. }
  1395.  
  1396. struct sym *
  1397. lookup(id, f, x)
  1398. char *id;
  1399. {
  1400.     register struct sym *sp;
  1401.     register char *p1, *p2;
  1402.     register int fihash, lasthash, i;
  1403.  
  1404.     lasthash = fihash = hash(id);
  1405.     for(i = 0; i < HASHSIZ; i++) {
  1406.         sp = &sym[lasthash];
  1407.         p1 = id;
  1408.         p2 = sp->s_name;
  1409.         if(p2 == 0) break;     /* found free entry */
  1410.         else {
  1411.             if(strncmp(p1,p2,NCPS) != 0) {
  1412.                 lasthash += fihash;
  1413.                 lasthash %= HASHSIZ;
  1414.             }
  1415.             else return(sp);
  1416.         }
  1417.     }
  1418.     if (f == 0)
  1419.         return (NULL);
  1420.     if(i == HASHSIZ)
  1421.         error("Too many symbols!\n");
  1422.     ninst++;        /* increment # of install in table */
  1423.     if(x == 1)
  1424.         sp->s_name = id;
  1425.     else {
  1426.         p2 = malloc((strlen(id) + 1));
  1427.         sp->s_name = p2;
  1428.         p1 = id;
  1429.         strcpy(p2, p1);
  1430.     }
  1431.     sp->s_type = S_UND;
  1432.     sp->s_flag = 0;
  1433.     sp->s_addr = 0;
  1434.     return (sp);
  1435. }
  1436.  
  1437. /* compute hashindex of string    */
  1438.  
  1439. hash(str)
  1440. char *str;
  1441. {
  1442.     register unsigned int i;
  1443.     register char c;
  1444.  
  1445.     i = 0;
  1446.     while((c = *str++) != 0)
  1447.         i += ( (int) c) & 0377;
  1448.     i %= HASHSIZ;
  1449.     if(i == 0 )
  1450.         i++;        /* since we use 'add the hash rehash' */
  1451.     return(i);
  1452. }
  1453.  
  1454. aerr()
  1455. {
  1456.     err('a');
  1457. }
  1458.  
  1459. err(c)
  1460. register c;
  1461. {
  1462.     register char *p;
  1463.  
  1464.     p = eb;
  1465.     while (p < ep)
  1466.         if (c == *p++)
  1467.             return;
  1468.     if (p < &eb[NERR]) {
  1469.         *p++ = c;
  1470.         ep = p;
  1471.     }
  1472.     if (c == 'q') {
  1473.         ++eflag;
  1474.         longjmp(env, 0);
  1475.     }
  1476. }
  1477.  
  1478. error(str)
  1479. char *str;
  1480. {    fprintf(stderr, str);}
  1481.  
  1482. diag()
  1483. {
  1484.     register char *p;
  1485.  
  1486.     p = eb;
  1487.     while (p < ep)
  1488.         printf("%c %04d %s\n", *p++, line, ib);
  1489. }
  1490.  
  1491. outw(w)
  1492. register w;
  1493. {
  1494.     outb(w>>8);
  1495.     outb(w);
  1496. }
  1497.  
  1498. outb(b)
  1499. register b;
  1500. {
  1501.     if (pass != 0) {
  1502.         if (cp >= &cb[NCODE])
  1503.             err('z');
  1504.         else
  1505.             *cp++ = b;
  1506.         if (!nflag) {
  1507.             if (bo>=NBIN || ba+bo!=dot->s_addr) {
  1508.                 bflush();
  1509.                 ba = dot->s_addr;
  1510.                 bo = 0;
  1511.             }
  1512.             bb[bo++] = b;
  1513.         }
  1514.     }
  1515.     ++dot->s_addr;
  1516. }
  1517.  
  1518. bflush()
  1519. {
  1520.     register b, c, i;
  1521.  
  1522.     if (bo == 0)
  1523.         return;
  1524.     fprintf(ofp, ":%02x%04x00", bo, ba);
  1525.     c = bo + ba + (ba>>8);
  1526.     for (i=0; i<bo; ++i) {
  1527.         b = bb[i]&0377;
  1528.         fprintf(ofp, "%02x", b);
  1529.         c += b;
  1530.     }
  1531.     fprintf(ofp, "%02x\n", (-c)&0377);
  1532. }
  1533.  
  1534. beof()
  1535. {
  1536.     register int dummy;
  1537.  
  1538.     dummy = ((startadr & 0377) + (startadr >> 8) + 1) & 0377;
  1539.     dummy = -dummy & 0377;
  1540.  
  1541.     if (startadr == 0xffff)         /* not given */
  1542.         fprintf(ofp, ":0000000000\n");
  1543.     else
  1544.         fprintf(ofp, ":00%04x01%02x\n", startadr, dummy);
  1545. }
  1546.  
  1547. /*
  1548.  * install z8 opcodes
  1549.  */
  1550. insopc()
  1551. {
  1552.     register struct sym *sp;
  1553.     register struct sym *pp;
  1554.  
  1555.     for (sp = optab;;) {
  1556.         if (*(sp->s_name) == 0)
  1557.             return;
  1558.         pp = lookup(sp->s_name, 1, 1);
  1559.         if(pp == NULL) {
  1560.             fprintf(stderr,"hashtable-error with symbol: %s\n", sp->s_name);
  1561.             exit(1);
  1562.         }
  1563.         pp->s_type = sp->s_type;
  1564.         pp->s_flag = sp->s_flag;
  1565.         pp->s_addr = sp->s_addr;
  1566.         sp++;
  1567.     }
  1568. }
  1569.  
  1570. struct sym optab[] = {
  1571.     ".",            S_ABS,          S_ASG,  0,
  1572.     ".byte",        S_BYTE,         0,      0,
  1573.     ".word",        S_WORD,         0,      0,
  1574.     ".ascii",       S_ASCII,        0,      0,
  1575.     ".asciz",       S_ASCIZ,        0,      0,
  1576.     ".blkb",        S_BLKB,         0,      0,
  1577.     ".page",        S_PAGE,         0,      0,
  1578.     ".title",       S_TITLE,        0,      0,
  1579.     ".hlist",       S_HLIST,        0,      1,
  1580.     ".olist",       S_OLIST,        0,      0,
  1581.     ".list",        S_LIST,         0,      0,
  1582.     ".nlist",       S_NLIST,        0,      0,
  1583.     ".end",         S_START,        0,      0,
  1584.  
  1585.     "ccf",          S_OP0,          0,      0xef,
  1586.     "di",           S_OP0,          0,      0x8f,
  1587.     "ei",           S_OP0,          0,      0x9f,
  1588.     "reti",         S_OP0,          0,      0xbf,
  1589.     "nop",          S_OP0,          0,      0xff,
  1590.     "rcf",          S_OP0,          0,      0xcf,
  1591.     "ret",          S_OP0,          0,      0xaf,
  1592.     "scf",          S_OP0,          0,      0xdf,
  1593.  
  1594.     "srp",          S_OP2,          0,      0x31,
  1595.  
  1596.     "clr",          S_OP3,          0,      0xb0,
  1597.     "com",          S_OP3,          0,      0x60,
  1598.     "da",           S_OP3,          0,      0x40,
  1599.     "dec",          S_OP3,          0,      0,
  1600.     "pop",          S_OP3,          0,      0x50,
  1601.     "push",         S_OP3,          0,      0x70,
  1602.     "rl",           S_OP3,          0,      0x90,
  1603.     "rlc",          S_OP3,          0,      0x10,
  1604.     "rr",           S_OP3,          0,      0xe0,
  1605.     "rrc",          S_OP3,          0,      0xc0,
  1606.     "sra",          S_OP3,          0,      0xd0,
  1607.     "swap",         S_OP3,          0,      0xf0,
  1608.  
  1609.     "call",         S_OP4,          0,      0,
  1610.  
  1611.     "jmp",          S_OP5,          0,      0x8d,
  1612.     "jcs",          S_OP5,          0,      0x7d,
  1613.     "jcc",          S_OP5,          0,      0xfd,
  1614.     "jeq",          S_OP5,          0,      0x6d,
  1615.     "jne",          S_OP5,          0,      0xed,
  1616.     "jpl",          S_OP5,          0,      0xdd,
  1617.     "jmi",          S_OP5,          0,      0x5d,
  1618.     "jov",          S_OP5,          0,      0x4d,
  1619.     "jnov",         S_OP5,          0,      0xcd,
  1620.     "jge",          S_OP5,          0,      0x9d,
  1621.     "jlt",          S_OP5,          0,      0x1d,
  1622.     "jgt",          S_OP5,          0,      0xad,
  1623.     "jle",          S_OP5,          0,      0x2d,
  1624.     "juge",         S_OP5,          0,      0xfd,
  1625.     "jult",         S_OP5,          0,      0x7d,
  1626.     "jugt",         S_OP5,          0,      0xbd,
  1627.     "jule",         S_OP5,          0,      0x3d,
  1628.  
  1629.     "br",           S_OP6,          0,      0x8b,
  1630.     "bcs",          S_OP6,          0,      0x7b,
  1631.     "bcc",          S_OP6,          0,      0xfb,
  1632.     "beq",          S_OP6,          0,      0x6b,
  1633.     "bne",          S_OP6,          0,      0xeb,
  1634.     "bpl",          S_OP6,          0,      0xdb,
  1635.     "bmi",          S_OP6,          0,      0x5b,
  1636.     "bov",          S_OP6,          0,      0x4b,
  1637.     "bnov",         S_OP6,          0,      0xcb,
  1638.     "bge",          S_OP6,          0,      0x9b,
  1639.     "blt",          S_OP6,          0,      0x1b,
  1640.     "bgt",          S_OP6,          0,      0xab,
  1641.     "ble",          S_OP6,          0,      0x2b,
  1642.     "buge",         S_OP6,          0,      0xfb,
  1643.     "bult",         S_OP6,          0,      0x7b,
  1644.     "bugt",         S_OP6,          0,      0xbb,
  1645.     "bule",         S_OP6,          0,      0x3b,
  1646.  
  1647.     "sob",          S_OP7,          0,      0x0a,
  1648.  
  1649.     "add",          S_OP8,          0,      0x00,
  1650.     "adc",          S_OP8,          0,      0x10,
  1651.     "sub",          S_OP8,          0,      0x20,
  1652.     "sbc",          S_OP8,          0,      0x30,
  1653.     "or",           S_OP8,          0,      0x40,
  1654.     "and",          S_OP8,          0,      0x50,
  1655.     "tcm",          S_OP8,          0,      0x60,
  1656.     "tm",           S_OP8,          0,      0x70,
  1657.     "cmp",          S_OP8,          0,      0xa0,
  1658.     "xor",          S_OP8,          0,      0xb0,
  1659.  
  1660.     "mov",          S_OP9,          0,      0,
  1661.  
  1662.     "incw",         S_OP10,         0,      0xa0,
  1663.     "decw",         S_OP10,         0,      0x80,
  1664.  
  1665.     "inc",          S_OP11,         0,      0x20,
  1666.     "dec",          S_OP12,         0,      0,
  1667.  
  1668. /*      movp    is      ldc     'move from/to program memory' */
  1669. /*      movd    is      lde     'move from/to data memory' */
  1670. /*      movpi   is      ldci    'move from/to prog. mem autoincr.' */
  1671. /*      movdi   is      ldei    'move from/to data mem autoincr.' */
  1672. /* s_flag contains first line of inst. summary */
  1673. /* s_addr contains second line */
  1674.  
  1675.     "movp",         S_OP13,         0xc2,   0xd2,
  1676.     "movd",         S_OP13,         0x82,   0x92,
  1677.     "movfpi",       S_OP14,         0,      0xc3,
  1678.     "movfdi",       S_OP14,         0,      0x83,
  1679.     "movtpi",       S_OP15,         0,      0xd3,
  1680.     "movtdi",       S_OP15,         0,      0x93,
  1681.     "",             0,              0,      0
  1682. };
  1683.